# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _

import math

FAPIAO_LINE_NAME_MAX = 28
FAPIAO_LINE_SPEC_MAX = 28

# sale wizard
# 分组规则
#  建立 模型定义分组规则
#  分组选择项目是 明细行上的字段名
#
# 行数设置
#  根据明细行的 商品分类名称 + 产品名称 计算总长度
#  根据总长度, 计算行数
#  带折扣的 行数翻倍
#  单行 / 八行 / 多行
#
# 公司表设置 发票限额 不含税100万
#
# 明细行排序
#  通用的按照 sequence 排序
#  继承后 按照自定义排序


class SaleOrderLine(models.Model):
    _inherit = 'fp.sale.order.line'

    def fapiao_line_count_get(self):
        # product_categ_name = self.product_categ_name or ''
        # product_name = self.product_name or ''

        # name1 = '*' + product_categ_name + '*' + product_name
        # spec = self.product_spec or ''
        # length1 = len(name1.encode('gbk'))
        # length2 = len(spec.encode('gbk'))
        # count1 = math.ceil(length1/FAPIAO_LINE_NAME_MAX)
        # count2 = math.ceil(length2/FAPIAO_LINE_SPEC_MAX)
        # count = count1 > count2 and count1 or count2
        count = 1

        if self.amount_discount < 0:
            count = count * 2

        return count


class SaleSplit(models.Model):
    _inherit = "fp.sale.split"

    def split_order_line(self, lines):

        def check_group_equ(one, line):
            codes = self.split_group_ids.mapped('code')
            for code in codes:
                if one[code] != line[code]:
                    return False
            return True

        def group_by_find_in_done(done, line):
            for i, ones in enumerate(done):
                one = ones[0]
                if check_group_equ(one, line):
                    return (True, i, ones)

            return (False, None, None)

        def group_by():
            if not self.split_group_ids:
                return [lines]

            dones = []
            for line in lines:
                res, index, old = group_by_find_in_done(dones, line)
                if res:
                    dones[index] = old | line
                else:
                    dones.append(line)

            return dones

        def group_by_linenum_max(groups):

            res = []

            for group in groups:
                # todo 总金额超限 再拆分一次
                # totla_ammount = 0

                count = 0
                current = None

                for line in group:
                    count_one = line.fapiao_line_count_get()
                    if not current:
                        count = count_one
                        current = line
                    elif count + count_one > 8:
                        res.append(current)
                        count = count_one
                        current = line
                    elif count + count_one == 8:
                        res.append(current | line)
                        count = 0
                        current = None
                    else:  # count + count_one < 8
                        count = count + count_one
                        current = current | line

                if current:
                    res.append(current)

            return res

        if self.linenum_select == 'one':
            return [line for line in lines]

        groups = group_by()
        if self.linenum_select == 'max':
            return group_by_linenum_max(groups)

        else:  # self.linenum_select == 'all' # 全行一单
            return groups


class Sale2FapiaoWizard(models.TransientModel):
    _name = "fp.sale2fapiao.wizard"
    _description = "Sales2Fapiao Wizard"

    sale_order_ids = fields.Many2many(
        'fp.sale.order',
        'fp_sale2fapiao_sale_rel',
        'wizard_id', 'sale_order_id',
        string="Sale Order", readonly=True, copy=False,)

    invoice_type = fields.Selection(
        selection=[
            ('vat_special', '增值税专用发票'),
            ('vat_general', '增值税普通发票'),
            ('vat_general_e', '增值税电子普通发票'),
            ('vat_special_e', '增值税电子专用发票'),
            # ('40', '货物运输业增值税专用发票'),
            # ('50', '机动车销售统一发票'),
            # ('60', '卷式发票'),
            # ('70', '二手车发票'),
            # ('80', '通行费发票'),
        ], default='vat_general_e', required=True,)

    def _get_default_split_id(self):
        split = self.env['fp.sale.split'].search([], order="id", limit=1)
        return split

    split_id = fields.Many2one(
        'fp.sale.split',
        string='Split Method', required=True,
        default=_get_default_split_id,
        help="")

    @api.model
    def _values_get_by_sale(self, sale_orders):
        return {
            'sale_order_ids': [(6, 0, sale_orders.ids)],
        }

    def onchange(self, values, field_name, field_onchange):
        result = super().onchange(values, field_name, field_onchange)

        if field_name:
            return result

        active_ids = self._context.get('active_ids', [])
        sale_obj = self.env['fp.sale.order']
        sale_orders = sale_obj.browse(active_ids)

        default_vals = self._values_get_by_sale(sale_orders)
        result['value'].update(default_vals)
        return result

    @api.model_create_multi
    def create(self, vals_list):
        # self._context.get('active_model') == 'fp.ods.sale.order'
        active_ids = self._context.get('active_ids', [])

        active_ids = self._context.get('active_ids', [])
        sale_obj = self.env['fp.sale.order']
        sale_orders = sale_obj.browse(active_ids)

        for vals in vals_list:
            default_vals = self._values_get_by_sale(
                sale_orders)
            vals.update(default_vals)

        records = super().create(vals_list)

        return records

    def _values_list_get_for_fapiao_line(self, sale_line_ids):
        # line_ids 排序 依赖于 HW

        def call_default():
            values_list = []
            for line in sale_line_ids:
                vals = {
                    # 'client_line_ref': line.client_line_ref,
                    'sale_line_ids': [(6, 0, line.ids)],
                    'name': line.name,
                    'sequence': line.sequence,
                    # 'line_type': 'line',  todo
                    'product_id': line.product_id.id,
                    'tax_ratio': line.tax_ratio,
                    'quantity': line.quantity,
                    'amount_untaxed': line.amount_untaxed,
                    'amount_tax': line.amount_tax,
                }

                values_list.append(vals)

            return values_list

        def call_merge():
            product = self.split_id.split_product_id.product_id
            vals = {
                # 'client_line_ref': line.client_line_ref,
                'sale_line_ids': [(6, 0, sale_line_ids.ids)],
                'name': product.name,
                # 'sequence': line.sequence,
                'product_id': product.id,
                'tax_ratio': sale_line_ids[0].tax_ratio,
                'quantity': 1,
                'amount_untaxed': sum(sale_line_ids.mapped('amount_untaxed')),
                'amount_tax':  sum(sale_line_ids.mapped('amount_tax')),
            }
            return [vals]

        if not sale_line_ids:
            return []

        if self.split_id.linenum_select == 'all':
            if self.split_id.split_product_id.has_prodcut:
                if self.split_id.split_product_id.product_id:
                    return call_merge()

        return call_default()

    def _values_list_get_for_fapiao(self, sale_order):

        sale_line_ids_groups = self.split_id.split_order_line(
            sale_order.line_ids)

        values_list = []

        def note_get(lines):
            if not lines:
                return ''
            elif self.split_id.note_select == 'order':
                return lines[0].order.note
            elif self.split_id.note_select == 'one':
                return lines[0].note
            else:  # self.split_id.note_select == 'no'
                return ''

        for sale_line_ids in sale_line_ids_groups:
            lines = self._values_list_get_for_fapiao_line(sale_line_ids)

            note = note_get(sale_line_ids)

            invoice_type = self.invoice_type

            if hasattr(sale_order, 'invoice_type'):
                invoice_type = sale_order.invoice_type

            comp_code = sale_order.company_id.company_registry

            saler_id = self.env['fp.partner'].search(
                [('code', '=', comp_code)], limit=1)

            vals = {
                'type': 'out_invoice',
                'invoice_type': invoice_type,
                'company_id': sale_order.company_id.id,
                'user_id': sale_order.user_id.id,
                'buyer_id': sale_order.fp_partner_id.id,
                'saler_id': saler_id.id,
                'note': note,
                'line_ids': lines and [
                    (0, 0, vals_line) for vals_line in lines] or []
            }

            values_list.append(vals)

        return values_list

    def create_fapiao(self):
        values_list = []
        for order in self.sale_order_ids:
            one_values_list = self._values_list_get_for_fapiao(order)
            values_list = values_list + one_values_list

        fapiao_obj = self.env['fp.fapiao']
        fapiaos = fapiao_obj.create(values_list)

        for order in self.sale_order_ids:
            order.action_done()

        return fapiaos.ids
